home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / mtools.lha / mtools-2.0.7 / fat_read.c < prev    next >
C/C++ Source or Header  |  1992-09-10  |  3KB  |  131 lines

  1. #include <stdio.h>
  2. #include "msdos.h"
  3.  
  4. #define CHK_FAT
  5.  
  6. int fat_len;                /* length of FAT table (in sectors) */
  7. unsigned int end_fat;            /* the end-of-chain marker */
  8. unsigned int last_fat;            /* the last in a chain marker */
  9. unsigned char *fat_buf;            /* the File Allocation Table */
  10.  
  11. extern int fat_bits;
  12. extern unsigned num_clus;
  13.  
  14. /*
  15.  * Get and decode a FAT (file allocation table) entry.  Returns the cluster
  16.  * number on success or 1 on failure.
  17.  */
  18.  
  19. unsigned int
  20. fat_decode(num)
  21. unsigned int num;
  22. {
  23.     unsigned int fat, fat_hi, fat_low, byte_1, byte_2, start;
  24.  
  25.     if (fat_bits == 12) {
  26.         /*
  27.          *    |    byte n     |   byte n+1    |   byte n+2    |
  28.          *    |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
  29.          *    | | | | | | | | | | | | | | | | | | | | | | | | |
  30.          *    | n+0.0 | n+0.5 | n+1.0 | n+1.5 | n+2.0 | n+2.5 |
  31.          *        \_____  \____   \______/________/_____   /
  32.          *          ____\______\________/   _____/  ____\_/
  33.          *         /     \      \          /       /     \
  34.          *    | n+1.5 | n+0.0 | n+0.5 | n+2.0 | n+2.5 | n+1.0 |
  35.          *    |      FAT entry k      |    FAT entry k+1      |
  36.          */
  37.                     /* which bytes contain the entry */
  38.         start = num * 3 / 2;
  39.         if (start <= 2 || start + 1 > (fat_len * MSECTOR_SIZE))
  40.             return(1);
  41.  
  42.         byte_1 = *(fat_buf + start);
  43.         byte_2 = *(fat_buf + start + 1);
  44.                     /* (odd) not on byte boundary */
  45.         if (num % 2) {
  46.             fat_hi = (byte_2 & 0xff) << 4;
  47.             fat_low = (byte_1 & 0xf0) >> 4;
  48.         }
  49.                     /* (even) on byte boundary */
  50.         else {
  51.             fat_hi = (byte_2 & 0xf) << 8;
  52.             fat_low = byte_1 & 0xff;
  53.         }
  54.         fat = (fat_hi + fat_low) & 0xfff;
  55.     }
  56.     else {
  57.         /*
  58.          *    |    byte n     |   byte n+1    |
  59.          *    |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
  60.          *    | | | | | | | | | | | | | | | | |
  61.          *    |         FAT entry k           |
  62.          */
  63.                     /* which bytes contain the entry */
  64.         start = num * 2;
  65.         if (start <= 3 || start + 1 > (fat_len * MSECTOR_SIZE))
  66.             return(1);
  67.  
  68.         fat = (*(fat_buf + start + 1) * 0x100) + *(fat_buf + start);
  69.     }
  70.     return(fat);
  71. }
  72.  
  73. /*
  74.  * Read the entire FAT table into memory.  Crude error detection on wrong
  75.  * FAT encoding scheme.
  76.  */
  77.  
  78. void
  79. fat_read(start)
  80. int start;
  81. {
  82.     int i, fat_size;
  83.     unsigned int buflen;
  84.     char *malloc();
  85.     void perror(), exit(), disk_read();
  86.  
  87. #ifdef INT16
  88.     long junk;
  89.     junk = (long) fat_len * MSECTOR_SIZE;
  90.     
  91.     if (junk > 65535L) {
  92.         fprintf(stderr, "fat_read: FAT table is too large\n");
  93.         exit(1);
  94.     }
  95. #endif /* INT16 */
  96.  
  97.     /*
  98.      * Let's see if the length of the FAT table is appropriate for
  99.      * the number of clusters and the encoding scheme
  100.      */
  101. #ifdef CHK_FAT
  102.     fat_size = (fat_bits == 12) ? (num_clus +2) * 3 / 2 : (num_clus +2) * 2;
  103.     fat_size = (fat_size / 512) + ((fat_size % 512) ? 1 : 0);
  104.     if (fat_size != fat_len) {
  105.         fprintf(stderr, "fat_read: Wrong FAT encoding?\n");
  106.         exit(1);
  107.     }
  108. #endif /* CHK_FAT */
  109.                     /* only the first copy of the FAT */
  110.     buflen = fat_len * MSECTOR_SIZE;
  111.     fat_buf = (unsigned char *) malloc(buflen);
  112.     if (fat_buf == NULL) {
  113.         perror("fat_read: malloc");
  114.         exit(1);
  115.     }
  116.                     /* read the FAT sectors */
  117.     for (i=start; i<start+fat_len; i++)
  118.         disk_read((long) i, &fat_buf[(i-start)*MSECTOR_SIZE], MSECTOR_SIZE);
  119.  
  120.                     /* the encoding scheme */
  121.     if (fat_bits == 12) {
  122.         end_fat = 0xfff;
  123.         last_fat = 0xff8;
  124.     }
  125.     else {
  126.         end_fat = 0xffff;
  127.         last_fat = 0xfff8;
  128.     }
  129.     return;
  130. }
  131.